{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "32d013f7",
   "metadata": {},
   "source": [
    "# L4: Production-ready techniques"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0d3bbc6",
   "metadata": {},
   "source": [
    "In this lesson, you are going to learn about some production techniques, and integrate them into a web app."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49412c5b",
   "metadata": {},
   "source": [
    "### Import required dependencies and load the API key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df8739ce-2780-4c8a-b52d-0fb81edaa365",
   "metadata": {
    "height": 199
   },
   "outputs": [],
   "source": [
    "import * as mod from \"https://deno.land/std@0.213.0/dotenv/mod.ts\";\n",
    "import { \n",
    "    Document, \n",
    "    VectorStoreIndex, \n",
    "    SimpleDirectoryReader,\n",
    "    RouterQueryEngine,\n",
    "    storageContextFromDefaults,\n",
    "    ContextChatEngine\n",
    "} from \"npm:llamaindex@0.1.12\"\n",
    "const keys = await mod.load({export:true}) // read API key from .env"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99e39887",
   "metadata": {},
   "source": [
    "## 1. Persisting your data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1407d627",
   "metadata": {},
   "source": [
    "### Set up a storage context"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "382754f9-07a9-4a05-849c-184ab340c882",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "const storageContext = await storageContextFromDefaults({\n",
    "  persistDir: \"./storage\",\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2de8fa27",
   "metadata": {},
   "source": [
    "### Load the data and create an index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0a83bc49-d1cf-43b8-b5f2-e229de0920ba",
   "metadata": {
    "height": 131
   },
   "outputs": [],
   "source": [
    "const documents = await new SimpleDirectoryReader().loadData({\n",
    "  directoryPath: \"./data\", // we have the React wikipedia page in here\n",
    "});\n",
    "let index = await VectorStoreIndex.fromDocuments(documents, {\n",
    "  storageContext\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70183617",
   "metadata": {},
   "source": [
    "### Let's ask it a question!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "afe86f98-219e-46ba-b577-39e29f8adbd0",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "let engine = await index.asQueryEngine()\n",
    "let response = await engine.query({query:\"What is JSX?\"})\n",
    "console.log(response.toString())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7607dfb3",
   "metadata": {},
   "source": [
    "### Get an index without parsing the documents "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2d47e4a-e6c0-415f-92be-45ebba67be98",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "let storageContext2 = await storageContextFromDefaults({\n",
    "    persistDir: \"./storage\",\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a91dad78",
   "metadata": {},
   "source": [
    "### Initialize the index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8d6f0326-7144-4b5b-95f5-ba5f3e9cfc21",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "let index2 = await VectorStoreIndex.init({\n",
    "    storageContext: storageContext2\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23ab2471",
   "metadata": {},
   "source": [
    "### Let's query it!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d154581a-2a5c-4143-ac49-c98107d8262f",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "let engine2 = await index2.asQueryEngine()\n",
    "let response2 = await engine2.query({query:\"What is JSX?\"})\n",
    "console.log(response2.toString())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "988aecd0",
   "metadata": {},
   "source": [
    "## 2. Chatting with your data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4bedb39c",
   "metadata": {},
   "source": [
    "### Create a retriever and a new chat engine"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19489e8c-d71a-4b21-bccf-245cd8be42ae",
   "metadata": {
    "height": 131
   },
   "outputs": [],
   "source": [
    "const retriever = index2.asRetriever();\n",
    "retriever.similarityTopK = 3;\n",
    "\n",
    "let chatEngine = new ContextChatEngine({\n",
    "    retriever,\n",
    "});\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d0bc17d",
   "metadata": {},
   "source": [
    "### Let's try it!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5eaebc17-aa7e-452b-ab89-493726fc66a2",
   "metadata": {
    "height": 199
   },
   "outputs": [],
   "source": [
    "let messageHistory = [\n",
    "    {\n",
    "        role: \"user\",\n",
    "        content: \"What is JSX?\"\n",
    "    },\n",
    "    {\n",
    "        role: \"assistant\",\n",
    "        content: \"JSX stands for JavaScript Syntax Extension. It is an extension to the JavaScript language syntax that provides a way to structure component rendering using syntax familiar to many developers. JSX is similar in appearance to HTML and is typically used to write React components, although components can also be written in pure JavaScript. It was created by Facebook and is similar to another extension syntax created for PHP called XHP.\"\n",
    "    }\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bc0a2005-096e-44f2-9949-06ff3419a011",
   "metadata": {
    "height": 46
   },
   "outputs": [],
   "source": [
    "let newMessage = \"What was that last thing you mentioned?\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1a18f788-f146-48b9-ba39-f224ad829327",
   "metadata": {
    "height": 97
   },
   "outputs": [],
   "source": [
    "const response3 = await chatEngine.chat({\n",
    "  message: newMessage,\n",
    "  chatHistory: messageHistory\n",
    "});\n",
    "console.log(response3.toString())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c466165",
   "metadata": {},
   "source": [
    "## 3. Streaming"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70fcbe70",
   "metadata": {},
   "source": [
    "### Setting stream to true!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67a85874-e775-4175-8936-0294020dbdd5",
   "metadata": {
    "height": 114
   },
   "outputs": [],
   "source": [
    "const response4 = await chatEngine.chat({\n",
    "  message: newMessage,\n",
    "  chatHistory: messageHistory,\n",
    "  stream: true,\n",
    "});\n",
    "console.log(response4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c719a935",
   "metadata": {},
   "source": [
    "### Check the response!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f61332af-1a63-44ec-8581-999345398fb3",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "for await (const data of response4) {\n",
    "    console.log(data.response); // Print the data\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f696259",
   "metadata": {},
   "source": [
    "## Create Llama App"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b732d778",
   "metadata": {},
   "source": [
    "### Let's see all three techniques in a real web app!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa48c2f5",
   "metadata": {},
   "source": [
    "We will use the utility functions in **utils.ts** file. \n",
    "\n",
    "**Note:** Go to `File` and click on `Open` to access the **utils.ts** file and all the code used in this lesson."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3f4395d9-875d-42e5-9349-ff298a6fb2e5",
   "metadata": {
    "height": 29
   },
   "outputs": [],
   "source": [
    "import { runCreateLlamaApp } from './utils.ts'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6396d481",
   "metadata": {},
   "source": [
    "**Note**: The below code might take a minute to complete. Once done, please click on the link to access the web app!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f2c044fa-68b3-4507-bfe1-a6f11aa22b61",
   "metadata": {
    "height": 29
   },
   "outputs": [],
   "source": [
    "runCreateLlamaApp()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "153b1eed",
   "metadata": {},
   "source": [
    "### Demonstrate streaming to the UI"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f613678",
   "metadata": {},
   "source": [
    "Please note that the link generated above is specific to your notebook and will display the web app set up with our data! \n",
    "\n",
    "Ask it some questions about React. You'll see it instantly answers with a stream."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
